package com.mmz.spring.aop.framework;

import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;




public class ReflectiveMethodInvocation implements MethodInvocation{
	
	protected final Object proxy;

	protected final Object target;

	protected final Method method;

	protected Object[] arguments;

	private final Class<?> targetClass;

	
	/**
	 * 拦截器列表，根据pointcut匹配
	 * that need dynamic checks.
	 */
	protected final List<?> interceptorsAndDynamicMethodMatchers;

	
	private int currentInterceptorIndex = -1;
	
	protected ReflectiveMethodInvocation(
			Object proxy, Object target, Method method, Object[] arguments,
			Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers) {

		this.proxy = proxy;
		this.target = target;
		this.targetClass = targetClass;
		this.method = method;
		this.arguments = arguments;
		this.interceptorsAndDynamicMethodMatchers = interceptorsAndDynamicMethodMatchers;
	}
	
	public Object proceed() throws Throwable {
		//	当前索引等于最后一个，即拦截器调用完成，调用方法本体
		if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
			this.method.setAccessible(true);
			
			return method.invoke(target, arguments);
		}

		Object interceptorOrInterceptionAdvice =
				this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
		
			return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
		}

	public Object[] getArguments() {
		// TODO Auto-generated method stub
		return this.arguments;
	}

	public Object getThis() {
		// TODO Auto-generated method stub
		return this.target;
	}

	public AccessibleObject getStaticPart() {
		// TODO Auto-generated method stub
		return null;
	}

	public Method getMethod() {
		// TODO Auto-generated method stub
		return this.method;
	}
	

}
